/*
 * Galaxium Messenger
 * 
 * Copyright (C) 2008 Philippe Durand <draekz@gmail.com>
 * 
 * License: GNU General Public License (GPL)
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

using System;
using System.IO;
using System.Threading;

//using GLib;
using Gtk;

using Galaxium.Gui;
using Galaxium.Gui.GtkGui;
using Galaxium.Client;
using Galaxium.Protocol;
using Galaxium.Core;

using Anculus.Core;
using Anculus.Gui;

namespace Galaxium.Client.GtkGui
{
	public static class GtkActivityPreProcessor
	{
		private static IConfigurationSection Config = Configuration.Activity.Section;
		private static int MaxMessageLength = 35;
		
		private static Gdk.Pixbuf GenerateContactImage (IContact contact)
		{
			IIconSize iconSize = IconSizes.Large;
			ContactTreeDetailLevel detailLevel = ContactTreeDetailLevel.Detailed;
			Gdk.Pixbuf pixbuf = null;
			
			if (contact.DisplayImage != null && contact.DisplayImage.ImageBuffer != null && !contact.SupressImage)
			{
				try
				{
					if (contact.Presence.BasePresence == BasePresence.Idle)
						pixbuf = PixbufUtility.GetShadedPixbuf(new Gdk.Pixbuf(contact.DisplayImage.ImageBuffer), detailLevel);
					else if (contact.Presence.BasePresence == BasePresence.Offline)
						pixbuf = IconUtility.GetIcon ("galaxium-offline", iconSize);
					else
						pixbuf = PixbufUtility.GetFramedPixbuf (new Gdk.Pixbuf(contact.DisplayImage.ImageBuffer), detailLevel);
				}
				catch
				{
					if (contact.Presence.BasePresence == BasePresence.Idle)
						pixbuf = IconUtility.GetIcon ("galaxium-idle", iconSize);
					else if (contact.Presence.BasePresence == BasePresence.Offline)
						pixbuf = IconUtility.GetIcon ("galaxium-offline", iconSize);
					else
						pixbuf = IconUtility.GetIcon ("galaxium-online", iconSize);
				}
			}
			else
			{
				if (contact.Presence.BasePresence == BasePresence.Idle)
					pixbuf = IconUtility.GetIcon ("galaxium-idle", iconSize);
				else if (contact.Presence.BasePresence == BasePresence.Offline)
					pixbuf = IconUtility.GetIcon ("galaxium-offline", iconSize);
				else
					pixbuf = IconUtility.GetIcon ("galaxium-online", iconSize);
			}
			
			return pixbuf;
		}
		
		private static void GenerateNotification (IActivity activity, string action, string title, string message, Gdk.Pixbuf pixbuf)
		{
			ThrowUtility.ThrowIfNull ("title", title);
			ThrowUtility.ThrowIfNull ("message", message);
			INotification notification = null;
			
			if (pixbuf != null)
				notification = new GtkNotification (title, message, pixbuf.SaveToBuffer("png"));
			else
				notification = new GtkNotification (title, message, null);
			
			NotificationUtility.Show (notification, 3000);
		}
		
		private static string GenerateAccountString (IActivity activity)
		{
			string header = string.Empty;
			
			header += "<b>Account:</b> "+activity.Session.Account.UniqueIdentifier;
			
			return header;
		}
		
		static void OnEntityPresenceChangeActivity (object sender, EntityPresenceChangeActivity activity)
		{
			if (activity.Entity is IContact)
			{
				if (Config.GetBool (Configuration.Activity.PresenceChanges.Name, Configuration.Activity.PresenceChanges.Default))
				{
					IContact contact = (IContact)activity.Entity;
					string message = string.Format("<span size=\"small\"><b>Name:</b> {1}\n<b>Presence:</b> {2}\n{0}</span>", GenerateAccountString (activity),
						GLib.Markup.EscapeText (MessageUtility.StripMarkup (contact.DisplayIdentifier, 
						contact.Session.Account.Protocol)), contact.Presence.State);
					
					GenerateNotification (activity, "presence_change", "Presence Changed", message, GenerateContactImage (contact));
				}
			}
			else if (activity.Entity is IAccount)
			{
				NotificationUtility.UpdateStatus(activity.Entity);
			}
		}
		
		static void OnEntityNameChangeActivity (object sender, EntityNameChangeActivity activity)
		{
			if (Config.GetBool (Configuration.Activity.NameChanges.Name, Configuration.Activity.NameChanges.Default))
			{
				IContact contact = (IContact)activity.Entity;
				string message = string.Format("<span size=\"small\"><b>Name:</b> {1}\n<b>New Name:</b> {2}\n{0}</span>", GenerateAccountString (activity),
				                               GLib.Markup.EscapeText (MessageUtility.StripMarkup (activity.Old, contact.Session.Account.Protocol)),
				                               GLib.Markup.EscapeText (MessageUtility.StripMarkup (contact.DisplayName, contact.Session.Account.Protocol)));
				
				GenerateNotification (activity, "name_change", "Display Name Changed", message, GenerateContactImage (contact));
			}
		}
		
		static void OnEntityMessageChangeActivity (object sender, EntityMessageChangeActivity activity)
		{
			if (Config.GetBool (Configuration.Activity.MessageChanges.Name, Configuration.Activity.MessageChanges.Default))
			{
				IContact contact = (IContact)activity.Entity;
				string message = string.Format ("<span size=\"small\"><b>Name:</b> {1}\n<b>Message:</b> {1}\n{0}</span>", GenerateAccountString (activity),
				                                GLib.Markup.EscapeText (MessageUtility.StripMarkup (contact.DisplayIdentifier, contact.Session.Account.Protocol)),
				                                GLib.Markup.EscapeText (MessageUtility.StripMarkup (contact.DisplayMessage, contact.Session.Account.Protocol)));
				
				GenerateNotification (activity, "message_change", "Personal Message Changed", message, GenerateContactImage (contact));
			}
		}
		
		static void OnEntityImageChangeActivity (object sender, EntityImageChangeActivity activity)
		{
			if (activity.Entity.DisplayImage.ImageBuffer.Length < 1)
				return;
			
			if (Config.GetBool (Configuration.Activity.ImageChanges.Name, Configuration.Activity.ImageChanges.Default))
			{
				IContact contact = (IContact)activity.Entity;
				string message = string.Format ("<span size=\"small\"><b>Name:</b> {1}\n{0}</span>", GenerateAccountString (activity),
				                                GLib.Markup.EscapeText (MessageUtility.StripMarkup (activity.Entity.DisplayIdentifier, activity.Entity.Session.Account.Protocol)));
				
				GenerateNotification (activity, "image_change", "Display Image Changed", message, GenerateContactImage (contact));
			}
		}
		
		static void OnReceivedMessageActivity (object sender, ReceivedMessageActivity activity)
		{
			int done = 0;
			
			if (WindowUtility<Widget>.GetWindow (activity.Conversation) != null)
				return;
			
			if (Config.GetBool (Configuration.Activity.NewConversations.Name, Configuration.Activity.NewConversations.Default))
			{
				IContact contact = (IContact)activity.Entity;
				string text = activity.Message.GetText ();
				
				if (text.Length > MaxMessageLength)
					text = text.Substring (0, MaxMessageLength) + "...";
				
				string message = string.Format ("<span size=\"small\"><b>Name:</b> {1}\n{0}\n<b>Message:</b> {2}</span>", GenerateAccountString (activity),
					GLib.Markup.EscapeText (MessageUtility.StripMarkup (contact.DisplayIdentifier, contact.Session.Account.Protocol)), text);
				
				GenerateNotification (activity, "received_message", "Incoming Message", message, GenerateContactImage (contact));
			}
		}
		
		static void OnReceivedOtherActivity (object sender, ReceivedOtherActivity activity)
		{
			if (Config.GetBool (Configuration.Activity.ProtocolSpecific.Name, Configuration.Activity.ProtocolSpecific.Default))
			{
				IContact contact = (IContact)activity.Entity;
				string message = string.Format("<span size=\"small\"><b>Name:</b> {1}\n{0}</span>", GenerateAccountString (activity),
					GLib.Markup.EscapeText (MessageUtility.StripMarkup (contact.DisplayIdentifier, contact.Session.Account.Protocol)));
				
				GenerateNotification (activity, "received_other", "Incoming Activity", message, GenerateContactImage (contact));
			}
		}
		
		static void OnReceivedFileActivity (object sender, ReceivedFileActivity activity)
		{
			if (Config.GetBool (Configuration.Activity.Transfers.Name, Configuration.Activity.Transfers.Default))
			{
				IContact contact = (IContact)activity.Entity;
				string message = string.Format ("{0}{1} is requesting to send you a file!", GenerateAccountString (activity),
					GLib.Markup.EscapeText (MessageUtility.StripMarkup (contact.DisplayIdentifier, contact.Session.Account.Protocol)));
				
				GenerateNotification (activity, "received_file", "Incoming File Transfer", message, GenerateContactImage (contact));
			}
		}
		
		static void OnNewContactActivity (object sender, NewContactActivity activity)
		{
			if (Config.GetBool (Configuration.Activity.NewContacts.Name, Configuration.Activity.NewContacts.Default))
			{
				string message = string.Format("{0}A new contact has added you to their list!\n{1}", GenerateAccountString (activity),
					GLib.Markup.EscapeText(activity.Contact == null ? activity.UniqueIdentifier : activity.Contact.UniqueIdentifier));
				
				GenerateNotification (activity, "new_contact", "New Contact", message, IconUtility.GetIcon ("galaxium-add-contact", IconSizes.Large));
			}
		}
	}
}